from datetime import datetime, date
from uuid import uuid4
from StringIO import StringIO
import json

from bayanihan.helpers import get_database_object, convert_database_to_dictionary

def validate_user(username, password):
    docs = get_database_object()
    view = "function(doc) { if ( (doc.type=='User') && (doc.properties.username=='%s') && (doc.properties.password=='%s') ) emit(doc.id, doc); }" % (username, password)
    user = docs.query(view)  
    
    if len(user):
        return 1
    else:
        return 0

def get_all_reports_from_a_deployment(deployment_name):
    docs = get_database_object()
    view = "function(doc) { if ( (doc.type=='Feature') && (doc.properties.deployment_id.toLowerCase()=='%s') ) emit(doc._id, doc); }" % (deployment_name.lower())
    return docs.query(view)

def does_this_user_own_that_deployment(username, deployment_id):
    docs = get_database_object()
    view = "function(doc) { if ((doc.type=='Deployment') && (doc.properties.deployment_owner.toLowerCase()=='%s') && (doc.properties.deployment_name.toLowerCase()=='%s')) emit(doc.id,doc.properties); }" % (username.lower(), deployment_id.lower())
    query_result = docs.query(view)
    
    if len(query_result):
        return 1
    else:
        return 0
    
def get_report_by_id(report_id):
    database = get_database_object()
    all_reports = convert_database_to_dictionary(database)
    report = all_reports[report_id]
    return report
    
def save_user_from_post_data(post_data):
    username = post_data['username']
    password = post_data['password']
    email = post_data['email']
    
    user_document = {
        'type': 'User',
        'properties': {
            'username': username,
            'password': password,
            'email': email,
            'date_created': date.today().isoformat(),
            'date_last_login': date.today().isoformat()
        }
    }
    print user_document
    database = get_database_object()
    user_id = username.replace(' ','') 
    database[user_id] = user_document

def save_report_from_post_data(post_data, username):
    deployment_id = post_data['deployment_name']
    report_title = post_data['title']
    report_date_event = post_data['date'] + ':00'
    report_latitude = post_data['latitude']
    report_longtitude = post_data['longtitude']
    report_description = post_data['description']
    report_index_name = post_data['index_name']
    report_index_level_name = post_data['index_level_name']
    report_index_level = post_data['index_level']
    
    number_index_levels = float(len(get_index_level_names(deployment_id)))
    report_severity = float(report_index_level)/number_index_levels
    report_date_event = datetime.strptime(report_date_event, "%m/%d/%Y %H:%M:%S").strftime("%Y-%m-%d %H:%M:%S")
    
    #get the color of the deployment
    report_color = get_color_from_deployment_name(deployment_id)
    
    report_document = {
        'type': 'Feature',
        'geometry': {
            'type': 'Point',
            'coordinates': [
                report_longtitude,
                report_latitude
            ]
        },
        'properties': {
            'title': report_title,
            'deployment_id': deployment_id,
            'report_by': username,  # deployment_owner is the reporter
            'index_name': report_index_name,
            'index_level_name': report_index_level_name,
            'index': report_index_level,
            'description': report_description,
            'date_event': report_date_event,
            'timestamp_submitted': datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
            'color': report_color,
            'severity': report_severity
        }
    }
    
    # doc id used is report_title but that is not a good choice since several reports could have the same title but for the mean time this will do  
    database = get_database_object()
    report_id = report_title.replace(' ','') 
    print report_document
    database[report_id] = report_document
    return report_id

def save_deployment_from_post_data(post_data, username):
    deployment_type = post_data['deployment_type']
    
    if deployment_type == "parent":
        deployment_name = post_data['parent_deployment_name']
        deployment_document = {'type': 'Deployment',
            'properties': {
                'deployment_name': deployment_name.replace(' ',''),
                'deployment_owner': username,
                'deployment_parent': '',
                'date_created': datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                'date_updated': datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                'members': [],
                'administrators': []
            }
        }
        
    elif deployment_type == "child":
        deployment_name = post_data['child_deployment_name']
        deployment_color = post_data['child_color']
        deployment_parent = post_data['deployment_parent']

        index_name = post_data['index_name']
        number_of_levels = post_data['number_of_levels']
        index_level_names = []
        
        for i in range(1, int(number_of_levels) + 1):
            level_name = post_data['level'+str(i)] 
            index_level_names.append(level_name)
      
        deployment_document = {'type': 'Deployment',
            'properties': {
                'deployment_name': deployment_name.replace(' ','') ,
                'deployment_owner': username,
                'deployment_parent': deployment_parent,
                'color_scheme': deployment_color,
                'index_name': index_name,
                'index_level_names' : index_level_names,
                'date_created': datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                'date_updated': datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                'is_public': 'true',
                'members': [],
                'administrators': []
            }
        }
    
    database = get_database_object()
    deployment_id = deployment_name.replace(' ','') 
    database[deployment_id] = deployment_document
    
def get_color_from_deployment_name(deployment_name):
    docs = get_database_object()
    
    view = "function(doc) { if ( (doc.type=='Deployment') && (doc.properties.deployment_name.toLowerCase()=='%s') ) emit(null,doc.properties.color_scheme);}" % (deployment_name.lower())
    
    reports = docs.query(view)
    
    for x in reports:
        return x.value

def get_all_parent_deployments(username):        
    docs = get_database_object()
    view = "function(doc) { if ( (doc.type=='Deployment') && (doc.properties.deployment_owner.toLowerCase() =='%s') && (doc.properties.deployment_parent=='') ) emit(doc.id,doc.properties); }" % (username.lower())
    return docs.query(view)

def get_all_child_deployments(username):    
    docs = get_database_object()
    deployment_list = get_deployment_list(username)
    child_deployments = [] 
    for parent in deployment_list:
        for child in deployment_list[parent]:
            child_deployments.append(child)
    return child_deployments
    
def get_all_children_from_a_parent_deployment(username, parent_deployment_name):
    docs = get_database_object()
    view = "function(doc) { if ((doc.type=='Deployment') && (doc.properties.deployment_owner.toLowerCase() == '%s') && (doc.properties.deployment_parent.toLowerCase() =='%s')) emit(doc.id,doc.properties); }" % (username.lower(), parent_deployment_name.lower())
    return docs.query(view)             

def get_deployment_list(username):
    children = []
    parents = []
    i = 0
    
    parent_deployments = get_all_parent_deployments(username)

    for x in parent_deployments:
        parent_deployment_name = x.value["deployment_name"]
        parents.append(parent_deployment_name)

        child_deployments = get_all_children_from_a_parent_deployment(username, parent_deployment_name)
        children.append([])

        for y in child_deployments:
            child_deployment_name = y.value["deployment_name"]
            children[i].append(child_deployment_name)
        i = i + 1;

    deployment_list={}
    for i in range(len(parents)):
        deployment_list[parents[i]] = children[i]
    
    return deployment_list

def get_index_details(deployment_id):
    index = {}
    index['index_name'] = get_index_name(deployment_id)
    index['index_level_names'] = get_index_level_names(deployment_id)
    return index

def get_index_level_names(deployment_id):
    docs = get_database_object()
    view = "function(doc) { if ((doc.type=='Deployment') && (doc.properties.deployment_name.toLowerCase() =='%s')) emit(doc.id,doc.properties.index_level_names); }" % (deployment_id.lower())   
    
    results = docs.query(view)
    
    for x in results:
        return x.value

def get_index_name(deployment_id):
    docs = get_database_object()
    view = "function(doc) { if ((doc.type=='Deployment') && (doc.properties.deployment_name.toLowerCase() =='%s')) emit(doc.id,doc.properties.index_name); }" % (deployment_id.lower())  
    
    results = docs.query(view)
    
    for x in results:
        return x.value
    
def create_feature_collection_for_every_child_deployment(username):
    deployment = {}
    parent_deployments = get_all_parent_deployments(username)

    for x in parent_deployments:
        parent_deployment_name = x.value["deployment_name"]

        child_deployments = get_all_children_from_a_parent_deployment(username, parent_deployment_name)
        
        for y in child_deployments:
            child_deployment_name = y.value["deployment_name"]
            feature_collection = create_feature_collection_for_a_child_deployment(username, child_deployment_name)
            deployment[child_deployment_name] = feature_collection
    return deployment
            
def create_feature_collection_for_a_child_deployment(username, deployment_id):
    docs =  get_database_object()
    view = "function(doc) { if ( (doc.type=='Deployment') && (doc.properties.deployment_owner.toLowerCase()=='%s') && (doc.properties.deployment_name.toLowerCase() =='%s') ) emit(doc.id,doc.properties); }" % (username.lower(), deployment_id.lower())
    deployment = docs.query(view)

    feature_collection = '{"type":"FeatureCollection","features":['
        
    for x in deployment:
        deployment_name = x.value["deployment_name"]
        view2 = "function(doc) { if ((doc.type=='Feature') && (doc.properties.deployment_id.toLowerCase() =='%s')) emit(doc.id,doc); }" % (deployment_name.lower())
        reports = docs.query(view2)
                
        for report in reports:
            io_str = StringIO()
            json.dump(report.value, io_str)
            feature_collection = feature_collection + io_str.getvalue() + ','
    
    if(len(reports)):
        feature_collection = feature_collection[0:-1] + ']}'
    else:
        feature_collection = ''
    return feature_collection

